

import {getHeaderSync} from "../enum/Header.js"
import Connect from "../class/Connect.js"
import Message from "../class/Message.js"
import MessageTool from "./MessageTool.js"
import StatusTool from "./StatusTool.js"
import SocketStatus from "../enum/SocketStatus.js"

export default class SmbRequest {
  /**
   * 测试
   * @param {Connect} connectObj
   * @param {Object} agreeObj
   * @param {Function} cb
  */
  static async request(connectObj, agreeObj, cb){

    try{
      await connectObj.initConnect()
    }catch(e){
      return
    }

    var headerStruc = getHeaderSync(
      connectObj.sessionId,
      connectObj.messageId++,
      agreeObj.command
    );

    var message = new Message()

    MessageTool.writeHeaders(message, headerStruc)

    MessageTool.writeBody(connectObj, message, agreeObj.structure.request)

    let msgLength = message.headerOffset + message.bodyOffset

    console.log("--request")
    console.log(message.headerBuffer.toString('hex') +"|"+ message.bodyBuffer.toString('hex'))

    // create NetBios package
    var buffer = Buffer.allocUnsafe(4 + msgLength);
    
    // write NetBios cmd
    buffer.writeUInt8(0x00, 0);

    // write message length  3字节  24位 
    // 第1字节，前8位。和24位的0xff0000 按位与，留下前8位。当前24位只有前8位有值，右移16位，移动到后8位，然后写入
    buffer.writeUInt8((0xff0000 & msgLength) >> 16, 1);

    // 第2，3字节，后16位。和16位的0xffff 按位与，留下后16位。然后写入。
    buffer.writeUInt16BE(0xffff & msgLength, 2);
    let offset = 4
    // write message content
    message.headerBuffer.copy(buffer, offset, 0);
    offset += message.headerOffset

    message.bodyBuffer.copy(buffer, offset, 0);

    connectObj.socket.write(buffer);
    connectObj.agreeObj = agreeObj

    return new Promise((resolve, reject) => {
      connectObj.onResponse = function(connectObj, message){
        agreeObj.onResponse && agreeObj.onResponse(connectObj, message)
        resolve(message)
      }
      connectObj.onError = reject
    })
  
  }


  static onResponse(socketStatus, connectObj, response){

    if (socketStatus == SocketStatus.END) { // 收到的是关闭连接的消息。抛出错误异常。
      connectObj.onError && connectObj.onError(socketStatus)
      return
    }

    if(!response){
      return
    }
    connectObj.responseBuffer = Buffer.concat([connectObj.responseBuffer, response]);

    // tcp报头4位。的第一位是0，后3位是消息长度。
    if (connectObj.responseBuffer.length < 4) {
      return
    }
    var msgLength = (connectObj.responseBuffer.readUInt8(1) << 16) + connectObj.responseBuffer.readUInt16BE(2);
    
    if (connectObj.responseBuffer.length < msgLength + 4) {
      return 
    }

    /**
     * @var { Buffer } buffer
     */
    var buffer = connectObj.responseBuffer.slice(4, msgLength + 4); // 截取数组，去除tcp报头

    var message = new Message();
    let agreeObj = connectObj.agreeObj

    var headerStruc = getHeaderSync(
      connectObj.SessionId,
      connectObj.messageId,
      agreeObj.command
    );

    MessageTool.readHeaders(message, headerStruc, buffer)
    MessageTool.readBody(message, agreeObj.structure.response, buffer.slice(message.headerOffset))

    if (connectObj.debug) {
      console.log('--response'); // eslint-disable-line no-console
      console.log(r.toString('hex')); // eslint-disable-line no-console
    }

    this.checkStatus(message)
    connectObj.responseBuffer = connectObj.responseBuffer.slice(msgLength + 4);
    connectObj.onResponse && connectObj.onResponse(connectObj, message)
    connectObj.onResponse = null
    
  }

    /**
   * 测试
   * @param {Message} message
   */
  static checkStatus(message){
    let status = StatusTool.getStatus(message.headerStrucFormat['Status'])
    console.log("status:", message.headerStrucFormat['Status'])
  }
}


